package com.youcheng.configcenter.factory;

import com.youcheng.configcenter.exception.ConfigCenterServiceException;
import com.youcheng.configcenter.provider.ConfigurableEnvironmentDecorator;
import com.youcheng.configcenter.provider.DataBaseConfigProvider;
import com.youcheng.configcenter.provider.GiteeConfigProvider;
import com.youcheng.configcenter.provider.RemoteConfigProvider;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils;

import java.util.Objects;
import java.util.Properties;

/**
 * @author sunhongmin
 */
public class RemoteConfigProviderFactory {
    private final ConfigurableEnvironmentDecorator configurableEnvironmentDecorator;

    public RemoteConfigProviderFactory(ConfigurableEnvironment environment) {
        this.configurableEnvironmentDecorator = new ConfigurableEnvironmentDecorator(environment);
    }

    public Properties getProperties() throws ConfigCenterServiceException {
        String remoteConfigProvider = configurableEnvironmentDecorator.getRemoteConfigProvider();
        if (!StringUtils.hasLength(remoteConfigProvider)) {
            return null;
        }

        if (Objects.equals(remoteConfigProvider, ConfigurableEnvironmentDecorator.GiteeConfigBean.PROVIDER)) {
            ConfigurableEnvironmentDecorator.GiteeConfigBean giteeConfigBean = configurableEnvironmentDecorator.loadGiteeConfigBean();
            return new GiteeConfigProvider(giteeConfigBean.getUrl(), giteeConfigBean.getToken()).load();
        } else if (Objects.equals(remoteConfigProvider, ConfigurableEnvironmentDecorator.DataBaseConfigBean.PROVIDER)) {
            ConfigurableEnvironmentDecorator.DataBaseConfigBean dataBaseConfigBean = configurableEnvironmentDecorator.loadDataBaseConfigBean();
            ConfigurableEnvironmentDecorator.ConfigFileConfigBean configFileConfigBean = configurableEnvironmentDecorator.loadConfigFileConfigBean();
            return new DataBaseConfigProvider(dataBaseConfigBean, configFileConfigBean).load();
        } else {
            return loadProvider();
        }
    }

    public Properties loadProvider() {
        try {
            Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(configurableEnvironmentDecorator.getRemoteConfigProvider());
            RemoteConfigProvider provider = (RemoteConfigProvider) clazz.getDeclaredConstructor((Class<?>) null).newInstance();
            return provider.load();
        } catch (Throwable e) {
            System.err.printf("加载自定义配置类发生错误[%s]%n", configurableEnvironmentDecorator.getRemoteConfigProvider());
            e.printStackTrace();
        }

        return null;
    }

}
